#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<unistd.h>
#include<pthread.h>

using namespace std;
#define NUM 3
class threadData
{
public:
    threadData(int number)
    {
        threadname="thread-"+to_string(number);
    }
public:
    string threadname;
};
int tickets=100;
void *getTickets(void *args)
{
    threadData *td=static_cast<threadData*>(args);
    const char*name=td->threadname.c_str();
    while(true)
    {
        if(tickets>0)
        {
            usleep(1000);
            printf("who=%s,get a ticket: %d\n",name,tickets);
            tickets--;
        }
        else break;
    }
    printf("%s ...quit\n",name);
    return nullptr;
}

int main()
{
    vector<pthread_t> tids;
    vector<threadData *> thread_datas;
    for(int i=0;i<NUM;i++)//创建多个线程
    {
        pthread_t tid;
        threadData*td=new threadData(i);
        thread_datas.push_back(td);
        pthread_create(&tid,nullptr,getTickets,thread_datas[i]);
        tids.push_back(tid);
    }
    for(auto thread:tids)//统一等待
    {
        pthread_join(thread,nullptr);
    }
    for(auto td:thread_datas)//统一释放
    {
         delete td;
    }
    return 0;
}

// #define NUM 3
// __thread int g_val=100;
// int *p=nullptr;//用来记录堆空间地址

// struct threadData
// {
//     string threadname;
// };
// //__thread threadData td;局部存储支支持内置类型
// string toHex(pthread_t tid)//
// {
//     char buffer[128];
//     snprintf(buffer,sizeof(buffer),"0x%x",tid);
//     return buffer;
// }
// void InitThreadData(threadData*td,int number)
// {
//     td->threadname="thread-"+to_string(number);
// }

// void* threadRoutine(void *args)//所有线程都执行该函数，可重入函数
// {
//     pthread_detach(pthread_self());//自己分离线程
//     threadData*td=static_cast<threadData*>(args);
//     if(td->threadname=="thread-2") p=&g_val;//访问线程2的局部变量
//     string tid=toHex(pthread_self());
//     int pid=getpid();
//     int i=0;
//     while(i<NUM)
//     {
//         printf("threadname；%s,tid:%s,pid:%d\n,g_val:%d,&g_val:%p\n",
//         td->threadname.c_str(),tid.c_str(),pid,g_val,&g_val);
//         //sleep(1);
//         i++,g_val++;
//     }
//     delete td;
//     return nullptr;
// }
// int main()
// {
//     vector<pthread_t>tids;//记录每个线程的标识符信息
//     for(int i=0;i<NUM;i++)//创建多个线程
//     {
//         pthread_t tid;
//         threadData*td=new threadData;
//         InitThreadData(td,i);
//         pthread_create(&tid,nullptr,threadRoutine,td);
//         tids.push_back(tid);
//     }
//     sleep(1);//确保线程都创建成功
//     cout<<"main thread get a local value, val:"<<*p<<",&val:"<<p<<endl;
//     // for(auto i:tids)
//     // {
//     //     pthread_detach(i);//主线程来分离线程
//     // }
    
//     for(int i=0;i<tids.size();i++)//等待回收多个线程
//     {
//         int n=pthread_join(tids[i],nullptr);
//         printf("n=%d,who=0x%x,why；%s\n",n,tids[i],strerror(n));
//     }
//     return 0;
// }